package in.muton.edushare.registration;

import in.muton.edushare.EduShareSession;
import in.muton.edushare.url.URLLoader;

import java.sql.Date;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.wicket.AttributeModifier;
import org.apache.wicket.Page;
import org.apache.wicket.RestartResponseException;
import org.apache.wicket.ajax.AjaxRequestTarget;
import org.apache.wicket.ajax.form.AjaxFormComponentUpdatingBehavior;
import org.apache.wicket.markup.html.WebPage;
import org.apache.wicket.markup.html.basic.Label;
import org.apache.wicket.markup.html.form.Button;
import org.apache.wicket.markup.html.form.Form;
import org.apache.wicket.markup.html.form.PasswordTextField;
import org.apache.wicket.markup.html.form.TextField;
import org.apache.wicket.markup.html.form.validation.EqualPasswordInputValidator;
import org.apache.wicket.markup.html.form.validation.FormComponentFeedbackBorder;
import org.apache.wicket.markup.html.panel.FeedbackPanel;
import org.apache.wicket.model.Model;
import org.apache.wicket.model.PropertyModel;
import org.apache.wicket.protocol.http.RequestUtils;
import org.apache.wicket.validation.validator.EmailAddressValidator;
import org.apache.wicket.validation.validator.PatternValidator;
import org.apache.wicket.validation.validator.StringValidator;

import com.edushare.common.constants.ApplicationConstants;
import com.edushare.common.constants.ConfigPropertyName;
import com.edushare.common.constants.URLConstants;
import com.edushare.common.dao.ConfigPropertiesDAO;
import com.edushare.common.dao.TempUserDAO;
import com.edushare.common.dao.UniversitiesDAO;
import com.edushare.common.dao.UsersDAO;
import com.edushare.common.exceptions.ProcessingException;
import com.edushare.common.global.SystemGlobals;
import com.edushare.common.orm.ORMInterface;
import com.edushare.common.util.StringUtil;
import com.edushare.common.vo.ConfigProperties;
import com.edushare.common.vo.TempUsers;
import com.edushare.common.vo.UserRoles;
import com.edushare.common.vo.Users;

public class AdminRegistration extends WebPage {

	private static final long serialVersionUID = 6042125342094721500L;
	private TempUsers unregisteredUser = null;
	private static Log log = LogFactory.getLog(AdminRegistration.class);
	private Label warningLabel;
	
	public AdminRegistration() {
		initReg();
	}
	
	
	private void initReg(){
		
		System.out.println("SystemGlobals.getInstance().getConfigProperty(ConfigPropertyName.SUPPORT_BOOT)" + 
												SystemGlobals
													.getInstance()
													.getConfigProperty(ConfigPropertyName.SUPPORT_BOOT)
							);
		/** Access to boot condition and Admins only */
		//IF this is not the first boot
		if(
				!SystemGlobals
					.getInstance()
					.getConfigProperty(ConfigPropertyName.SUPPORT_BOOT)
					.equalsIgnoreCase("true")
					
		){
			//if user is not logged in, ask him to
			if(!EduShareSession.get().isLoggedIn())
				throw new RestartResponseException(URLLoader.getPageClass(URLConstants.LOGIN_PATH));
			else //if logged-in check if he is Admin of any university
			{
				Users user = EduShareSession.get().getLoggedInUser();
				boolean isAdmin = false;
				for(UserRoles role: user.getRoleList()){
					if(role.getRoleType() == UserRoles.ADMIN_ROLE){
						isAdmin = true;
						break;
					}
				}
				if(!isAdmin)
					throw new RestartResponseException(URLLoader.getPageClass(URLConstants.UNAUTHORIZED_PATH));
			}
			
		}
		
		
		unregisteredUser = new TempUsers();
		Form<Void> regForm = new Form<Void>("regform");
		
		add(regForm);
		final FeedbackPanel feedback;
		add(feedback = new FeedbackPanel("info"));
		feedback.setOutputMarkupId(true);
		
		regForm.add(new TextField<String>("fname", new PropertyModel<String>(unregisteredUser, "firstName")).setRequired(true));
		regForm.add(new TextField<String>("lname", new PropertyModel<String>(unregisteredUser, "lastName")).setRequired(true));
		TextField<String> emailField = new TextField<String>("email", new PropertyModel<String>(unregisteredUser, "email"));
		emailField.setRequired(true);
		emailField.add(EmailAddressValidator.getInstance());
		regForm.add(emailField);
		final TextField<String> univName = new TextField<String>("univ", new PropertyModel<String>(unregisteredUser, "universityName"));
		univName.setRequired(true);
		regForm.add(univName);
		TextField<String> phone = new TextField<String>("phone", new PropertyModel<String>(unregisteredUser, "phoneNo"));
		phone.setRequired(true);
		phone.add(new PatternValidator(ApplicationConstants.PHONE_NUMBER_PATTERN));
		phone.add(StringValidator.maximumLength(ApplicationConstants.MAX_PHONE_NUM_LENGTH));
		regForm.add(phone);
		FormComponentFeedbackBorder border = new FormComponentFeedbackBorder("border");
		regForm.add(border);
		final TextField<String> uniqueName = new TextField<String>("uname", new PropertyModel<String>(unregisteredUser, "userName"));
		uniqueName.setRequired(true);
		uniqueName.add(StringValidator.minimumLength(ApplicationConstants.MIN_USERNAME_LENGTH));
		uniqueName.add(new PatternValidator(ApplicationConstants.UNIQUE_NAME_PATTERN));
		uniqueName.add(new AjaxFormComponentUpdatingBehavior("onblur") {
			
			private static final long serialVersionUID = 1L;

			@Override
			protected void onError(AjaxRequestTarget target, RuntimeException e) {
				target.addComponent(feedback);
				super.onError(target, e);
			}
			
			@Override
			protected void onUpdate(AjaxRequestTarget target) {
				target.addComponent(feedback);
				String requestedUID = unregisteredUser.getUserName();
				if(target!=null){
					if(requestedUID == null || requestedUID.trim().equals("")){
						warningLabel.add(new AttributeModifier("style", true, new Model<String>("color:red; font-weight:bold")));
						target.addComponent(warningLabel.setDefaultModelObject("INVALID&nbsp;INPUT").setEscapeModelStrings(false));
					}
					else if(new TempUserDAO(getSessionORMInterface()).isUserNameAvailable(requestedUID)){
						warningLabel.add(new AttributeModifier("style", true, new Model<String>("color:blue; font-weight:bold")));
						target.addComponent(warningLabel.setDefaultModelObject("AVAILABLE"));
					}
					else{
						warningLabel.add(new AttributeModifier("style", true, new Model<String>("color:red; font-weight:bold")));
						target.addComponent(warningLabel.setDefaultModelObject("UNAVAILABLE"));
					}
				}
			}
			
		});
		border.add(uniqueName);
		
		warningLabel = new Label("availability","");
		warningLabel.setOutputMarkupId(true);
		regForm.add(warningLabel);
		PasswordTextField pass1 = new PasswordTextField("pwd", new PropertyModel<String>(unregisteredUser, "password"));
		PasswordTextField pass2 = new PasswordTextField("pwdcnf", pass1.getModel());
		regForm.add(pass1);
		regForm.add(pass2);
		regForm.add(new EqualPasswordInputValidator(pass1, pass2));
		pass1.add(StringValidator.minimumLength(ApplicationConstants.MIN_PASSWORD_LENGTH));
		regForm.add(
				new Button("regbtn"){
					
					private static final long serialVersionUID = 7046900196567707280L;
					@Override
					public void onSubmit(){
						String univNameStr = univName.getInput();

						//If Invalid University Name
						if(!StringUtil.isValid(univNameStr)){
							warn("Invalid University Name");
						}
						// If University is already registered
						else if(!new UniversitiesDAO(getSessionORMInterface())
								.isUniversityNameUnique(univNameStr))
						{
							warn("This University already exists in EduShare System! Please chose a different university name. In case you need help, please visit http://muton.in/contact.html");
						}
						// If user details are invalid
						else if (!isValid(unregisteredUser)) 
						{
							warn("Invalid or Unavailable User Name.");
						}
						//if name is sensible
						else if(!StringUtil.IsMinNoOfAlphanumerics(unregisteredUser.getUserName(), 2)){
							warn("User name must contain at least two alpha-numeric characters");
						}
						else if(new UsersDAO(getSessionORMInterface()).getUsersByEMail(unregisteredUser.getEmail())!=null){
							warn("This Email-Id is already registerted.");
						}
						//If all checked are correct then
						else
						{
							try {
								unregisteredUser.setStatus(TempUsers.STATUS_NOT_VERIFIED);
								unregisteredUser.setTimestamp(new Date(System.currentTimeMillis()));
								String verifyUrl = RequestUtils.toAbsolutePath(URLConstants.VERIFY_PATH);
								new TempUserDAO(getSessionORMInterface())
													.createTempUser(unregisteredUser,verifyUrl);
								Page next = new RegistrationResponse(unregisteredUser);
								setResponsePage(next);
							} catch (ProcessingException e) {
								log.error("ERROR REGISTERING NEW USER", e);
								e.printStackTrace();
							}
						}
						
						/*invalidate first boot */
						ConfigProperties boot = 
							new ConfigPropertiesDAO(getSessionORMInterface()).getConfigProperty(ConfigPropertyName.SUPPORT_BOOT);
						boot.setValue("false");
						SystemGlobals.getInstance().resetSystemGlobals();
						
						getSessionORMInterface().commitAllChanges();
					}
					
					private boolean isValid(TempUsers unregisteredUser) {
						if(unregisteredUser==null || !StringUtil.isValid(unregisteredUser.getUserName())){
							return false;
						}else if(! new TempUserDAO(getSessionORMInterface()).isUserNameAvailable(unregisteredUser.getUserName())){
							return false;
						}else{
							return true;
						}
					}
					
				}
				);
		
	}
	
	private ORMInterface getSessionORMInterface() {
		return EduShareSession.get().getSessionORMInterface();
	}
}
